AWS Step Functionsで変数とJSONataを活用し、Passステートで組み込み関数を使用したりChoiceで分岐させてみた
はじめに
AWS Step Functionsの変数とJSONataを活用し、Passステートで処理を行ったり、Choiceで分岐させてみました。
以前、AWS Step Functionsで変数とJSONataが利用可能になるアップデートがありました。
AWS Step Functionsのステートマシン内でJSONataを利用することで、PassステートでJSONPathでは実現できなかった複雑な処理を行ったり、渡された値を変数として容易に活用してステートマシン内で処理を実行することが可能です。
また、JSONPath形式に加えてJSONataも利用できるようになったため、JSONataを活用した変数の記述方法について解説します。
処理例
今回の例として、ステートマシンで処理している内容は以下の通りです。参考にした元記事は以下です。
内容は、Amazon Connectで自動ヒアリングした内容をAmazon Bedrockで要約し、メール通知する方法を、Amazon Kinesis Data Streams(以下、KDS)とAWS Step Functionsを用いて実装したものです。
処理の内容は以下の通りです。
- Kinesis Data Streams(以下、KDS)からEventBridge Pipesを経由してステートマシンをトリガーする。
- ヒアリング内容であるコンタクト属性(recording)、コンタクトID、発信元電話番号などが渡される。
- コンタクト属性(recording)がnullではないか確認
- BedrockのClaudeを利用して、文字起こし内容を整形する
- 整形した内容をSNSトピックを通じてメール送信する
以下に構成図を示します。
ワークフローとしては、以下の図の通りです。各ステートごとに章立てで解説します。
各ステートにおいて、状態の入力(以降、ステートの入力)と状態の出力(以降、ステートの出力)は、以下の実行ログ(State View)から確認できます。
Pass state(Base64Decode)ステート
まずは、Pass state(Base64Decode)ステートについて解説します。
本ステートでは変数のみを設定し、[設定]と[出力]については特に記載しません。
EventBridge Pipes内でKDSからステートマシンに渡される内容は、以下のとおりです。
{
"eventSource": "aws:kinesis",
"eventVersion": "1.0",
"eventID": "shardId-000000000000:xxxxxxxxx",
"eventName": "aws:kinesis:record",
"invokeIdentityArn": "arn:aws:iam::xxxxxxxxxxxx:role/service-role/Amazon_EventBridge_Pipe_cm-hirai-voicemail-to-email-sf_cbcfa279",
"awsRegion": "ap-northeast-1",
"eventSourceARN": "arn:aws:kinesis:ap-northeast-1:xxxxxxxxxxxx:stream/cm-hirai",
"kinesisSchemaVersion": "1.0",
"partitionKey": "19a1c22c-399d-4c6b-b766-9832832c9005",
"sequenceNumber": "xxxxxxxxx",
"data": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"approximateArrivalTimestamp": 1733793205.123
}
上記のうちdata
はBase64でエンコードされているため、Pass state(Base64Decode)ステートでデコードし、次のステートでJSONデータをパースして以下のような値を取得できるようにします。
{
"data": {
"AWSAccountId": "012345678901",
"AWSContactTraceRecordFormatVersion": "2017-03-10",
"Agent": null,
"AgentConnectionAttempts": 0,
"AnsweringMachineDetectionStatus": null,
"Attributes": {
"recording": "お問い合わせ内容〇〇"
},
"Campaign": {
"CampaignId": null
},
"Channel": "VOICE",
"ConnectedToSystemTimestamp": "2024-12-10T01:11:43Z",
"ContactDetails": {},
"ContactId": "19a1c22c-399d-4c6b-b766-9832832c9005",
"CustomerEndpoint": {
"Address": "+81xxxxxxxx",
"Type": "TELEPHONE_NUMBER"
},
"CustomerVoiceActivity": null,
"DisconnectReason": "CONTACT_FLOW_DISCONNECT",
"DisconnectTimestamp": "2024-12-10T01:12:22Z",
"InitialContactId": null,
"InitiationMethod": "INBOUND",
"InitiationTimestamp": "2024-12-10T01:11:43Z",
"InstanceARN": "arn:aws:connect:ap-northeast-1:012345678901:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c",
"LastUpdateTimestamp": "2024-12-10T01:13:24Z",
"MediaStreams": [
{
"Type": "AUDIO"
}
],
"NextContactId": null,
"PreviousContactId": null,
"Queue": null,
"Recording": null,
"Recordings": null,
"References": [],
"ScheduledTimestamp": null,
"SegmentAttributes": {
"connect:Subtype": {
"ValueInteger": null,
"ValueMap": null,
"ValueString": "connect:Telephony"
}
},
"SystemEndpoint": {
"Address": "+81xxxxxxxx",
"Type": "TELEPHONE_NUMBER"
},
"Tags": {
"aws:connect:instanceId": "3ff2093d-af96-43fd-b038-3c07cdd7609c",
"aws:connect:systemEndpoint": "+81xxxxxxxx"
},
"TaskTemplateInfo": null,
"TransferCompletedTimestamp": null,
"TransferredToEndpoint": null,
"VoiceIdResult": null
}
}
変数
このステートで渡される値にはdata
が含まれています。
{
"data": "xxxxxxxIjIwMjQtMTItMTBUMDE6MTM6MjRaIiwiTWVkaWFTdHJlYW1zIjpbeyJUeXBlIjoiQVVESU8ifV0sIk5leHRDb250YWN0SWQiOm51bGwsIlByZXZpb3VzQ29udGFjdElkIjpudWxsLCJRdWV1ZSI6bnVsbCwiUmVjb3JkaW5nIjpudWxsLCJSZWNvcmRpbmdzIjpudWxsLCJSZWZlcmVuY2VzIjpbXSwiU2NoZWR1bGVkVGltZXN0YW1wIjpudWxsLCJTZWdtZW50QXR0cmlidXRlcyI6eyJjb25uZWN0OlN1YnR5cGUiOnsiVmFsdWVJbnRlZ2VyIjpudWxsLCJWYWx1ZU1hcCI6bnVsbCwiVmFsdWVTdHJpbmciOiJjb25uZWN0OlRlbGVwaG9ueSJ9fSwiU3lzdGVtRW5kcG9pbnQiOnsiQWRkcmVzcyI6Iis4MTUwMzA5MDI1MjkiLCJUeXBlIjoiVEVMRVBIT05FX05VTUJFUiJ9LCJUYWdzIjp7ImF3czpjb25uZWN0Omluc3RhbmNlSWQiOiIzZmYyMDkzZC1hZjk2LTQzZmQtYjAzOC0zYzA3Y2RkNzYwOWMiLCJhd3M6Y29ubmVjdDpzeXN0ZW1FbmRwb2ludCI6Iis4MTUwMzA5MDI1MjkifSwiVGFza1RlbXBsYXRlSW5mbyI6bnVsbCwiVHJhbnNmZXJDb21wbGV0ZWRUaW1lc3RhbXAiOm51bGwsIlRyYW5zZmVycmVkVG9FbmRwb2ludCI6bnVsbCwiVm9pY2VJZFJlc3VsdCI6bnVsbH0="}
data
はBase64でエンコードされているため、本ステートでデコードし、次のステートでJSONデータをパースします。
そのため、本ステートでは以下のように変数を設定します。data
をBase64デコードした値を変数名decodedData
として定義しました。
{
"decodedData": "{% $base64decode($states.input.data) %}"
}
変数内で「b」を入力すると、「$base64decode()」が候補として表示されます。
JSONataのドキュメントから、利用可能な関数を確認できます。base64decode
関数もその中に含まれています。
JSONataのドキュメント
ちなみに、AWS サービスの連携ステート(Task state)を利用する場合、リクエスト結果を$states.result
として変数にすることはできますが、$states.result
はAPI が成功した場合の結果を指します。
Pass stateは、APIの結果ではないため、$states.result
は利用できません。
Pass stateで処理した内容は、{% $base64decode($states.input.data) %}
と記載することで、変数にできます。
テスト
ステートでは、[テスト状態]からテストを実行できます。
[ステートの入力]を設定し、[テストを開始]からテストを実行すると、[アドバンスト]で変数の結果を確認できます。[ステートの出力]を設定していない場合、[ステートの入力]がそのまま[ステートの出力]として使用されます。
[変数]はBase64エンコードした内容が確認できます。
実行ログ(State View)からも確認できますが、Base64エンコードされた内容は確認できません。これは、出力が設定されていないためです。
ステートで[出力]を設定していない場合、実行ログのグラフビューの右から[変数]が確認できます。
"{"AWSAccountId":"xxxxxxxxxxxx","AWSContactTraceRecordFormatVersion":"2017-03-10","Agent":null,"AgentConnectionAttempts":0,"AnsweringMachineDetectionStatus":null,"Attributes":{"recording":"加湿 器 が 壊れ た の で 連絡 し まし た シライ ユウジ です 十 五 時 に また 連絡 下さい"},"Campaign":{"CampaignId":null},"Channel":"VOICE","ConnectedToSystemTimestamp":"2024-12-10T01:11:43Z","ContactDetails":{},"ContactId":"19a1c22c-399d-4c6b-b766-9832832c9005","CustomerEndpoint":{"Address":"+81xxxxxxxx","Type":"TELEPHONE_NUMBER"},"CustomerVoiceActivity":null,"DisconnectReason":"CONTACT_FLOW_DISCONNECT","DisconnectTimestamp":"2024-12-10T01:12:22Z","InitialContactId":null,"InitiationMethod":"INBOUND","InitiationTimestamp":"2024-12-10T01:11:43Z","InstanceARN":"arn:aws:connect:ap-northeast-1:xxxxxxxxxxxx:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c","LastUpdateTimestamp":"2024-12-10T01:13:24Z","MediaStreams":[{"Type":"AUDIO"}],"NextContactId":null,"PreviousContactId":null,"Queue":null,"Recording":null,"Recordings":null,"References":[],"ScheduledTimestamp":null,"SegmentAttributes":{"connect:Subtype":{"ValueInteger":null,"ValueMap":null,"ValueString":"connect:Telephony"}},"SystemEndpoint":{"Address":"+81xxxxxxxx","Type":"TELEPHONE_NUMBER"},"Tags":{"aws:connect:instanceId":"3ff2093d-af96-43fd-b038-3c07cdd7609c","aws:connect:systemEndpoint":"+81xxxxxxxx"},"TaskTemplateInfo":null,"TransferCompletedTimestamp":null,"TransferredToEndpoint":null,"VoiceIdResult":null}"
Pass state(ParseJSON)ステート
次に、Pass state(ParseJSON)ステートについて解説します。
本ステートでは、設定と出力については特に記載しません。そのため、コメントもありません。
変数
前のステートでdata
はBase64デコードされ(変数名decodedData
)、本ステートではJSONデータをパースして、data
から以下のような値を取得します。
文字起こし内容のコンタクト属性(recording)も確認できます。
{
"data": {
"AWSAccountId": "012345678901",
"AWSContactTraceRecordFormatVersion": "2017-03-10",
"Agent": null,
"AgentConnectionAttempts": 0,
"AnsweringMachineDetectionStatus": null,
"Attributes": {
"recording": "お問い合わせ内容〇〇"
},
"Campaign": {
"CampaignId": null
},
"Channel": "VOICE",
"ConnectedToSystemTimestamp": "2024-12-10T01:11:43Z",
"ContactDetails": {},
"ContactId": "19a1c22c-399d-4c6b-b766-9832832c9005",
"CustomerEndpoint": {
"Address": "+81xxxxxxxx",
"Type": "TELEPHONE_NUMBER"
},
"CustomerVoiceActivity": null,
"DisconnectReason": "CONTACT_FLOW_DISCONNECT",
"DisconnectTimestamp": "2024-12-10T01:12:22Z",
"InitialContactId": null,
"InitiationMethod": "INBOUND",
"InitiationTimestamp": "2024-12-10T01:11:43Z",
"InstanceARN": "arn:aws:connect:ap-northeast-1:012345678901:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c",
"LastUpdateTimestamp": "2024-12-10T01:13:24Z",
"MediaStreams": [
{
"Type": "AUDIO"
}
],
"NextContactId": null,
"PreviousContactId": null,
"Queue": null,
"Recording": null,
"Recordings": null,
"References": [],
"ScheduledTimestamp": null,
"SegmentAttributes": {
"connect:Subtype": {
"ValueInteger": null,
"ValueMap": null,
"ValueString": "connect:Telephony"
}
},
"SystemEndpoint": {
"Address": "+81xxxxxxxx",
"Type": "TELEPHONE_NUMBER"
},
"Tags": {
"aws:connect:instanceId": "3ff2093d-af96-43fd-b038-3c07cdd7609c",
"aws:connect:systemEndpoint": "+81xxxxxxxx"
},
"TaskTemplateInfo": null,
"TransferCompletedTimestamp": null,
"TransferredToEndpoint": null,
"VoiceIdResult": null
}
}
変数の設定は以下の通りです。
data
のJSONデータをパースするため、JSONataのparse
関数を利用します。
{
"data": "{% $parse($decodedData) %}",
"InitialContactId": "{% $parse($decodedData).ContactId %}",
"Time": "{% $parse($decodedData).InitiationTimestamp %}",
"CallerPhoneNumber": "{% $parse($decodedData).SystemEndpoint.Address %}"
}
- 変数名とその値は以下の通りです。
- data:data(JSONデータのパース結果)
- InitialContactId:contactId(コンタクトID)
- Time:initiationTimestamp(電話の対応日時)
- CallerPhoneNumber:aws:connect:systemEndpoint(架電の電話番号)
変数名data
以外の3つの変数は、後続のBedrockやSNSステートで利用します。
これらの変数は、Connectの問い合わせレコードをKDSにストリーミングされる際に、必ず存在しますのでこの時点で変数にします。
変数名data
を定義する理由は、次のChoiceステートでコンタクト属性recording
が存在するか確認するためです。
コンタクト属性recording
は、Connectの問い合わせレコードをKDSにストリーミングされる際に存在しない可能性があり、本ステートで変数にする場合、recording
が存在しなかった場合エラーになってしまいます。
本ステートの設定は以上です。
Passステートを組み合わせることも可能
ちなみに、Pass state(Base64Decode)ステートとPass state(ParseJSON)ステートは、一つのPass stateに以下の通り集約させることも可能です。
{
"data": "{% $parse($base64decode($states.input.data)) %}",
"InitialContactId": "{% $parse($base64decode($states.input.data)).ContactId %}",
"Time": "{% $parse($base64decode($states.input.data)).InitiationTimestamp %}",
"CallerPhoneNumber": "{% $parse($base64decode($states.input.data)).SystemEndpoint.Address %}"
}
data
をbase64デコードして、JSONデータをパースを1つのステートで行います。
変数とJSONataの処理を理解しやすくなるよう、今回は1つの処理ごとにステートを分けました。
Choiceステート
次に、Choiceステートについて解説します。
Rule
Ruleで設定したConditionは以下の通りです。data
にコンタクト属性recording
が存在するかをチェックします。
先ほど設定した変数名data
を利用します。
{% $data.Attributes.recording != null %}
recording
が存在する場合、その値を変数として設定します。この変数は後続のステートで利用されます。
{
"recording": "{% $data.Attributes.recording %}"
}
Default Rule
コンタクト属性recording
が存在しない場合、出力や変数は特に設定しません。
Pass stateを経由してEndに遷移します。
Choiceのみでも可能
余談ですが、Choiceステートで、Conditionと割り当てられた変数を以下のように設定すると、Pass state(Base64Decode)ステートとPass state(ParseJSON)ステートを省略できます。
{% $parse($base64decode($states.input.data)).Attributes.recording != null %}
{
"Type": "Choice",
"Choices": [
{
"Condition": "{% $parse($base64decode($states.input.data)).Attributes.recording != null %}",
"Next": "Bedrock InvokeModel",
"Assign": {
"recording": "{% $parse($base64decode($states.input.data)).Attributes.recording %}",
"InitialContactId": "{% $parse($base64decode($states.input.data)).ContactId %}",
"Time": "{% $parse($base64decode($states.input.data)).InitiationTimestamp %}",
"CallerPhoneNumber": "{% $parse($base64decode($states.input.data)).SystemEndpoint.Address %}"
}
}
],
"Default": "Pass"
}
今回は、ワークフローのわかりやすさを重視するため、3つのステートを利用しました。
Bedrock InvokeModel
次に、BedrockのInvokeModelステートについて解説します。
BedrockのClaudeモデルを利用して、文字起こし内容であるコンタクト属性recording
を整形します。
引数と出力
InvokeModelを実行するため、以下の引数を設定しました。
文字起こし内容であるrecording
を整形するためのプロンプトを指定しています。
{
"ModelId": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0",
"Body": {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"temperature": 0,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "{% '以下の音声文字起こしテキストから、ご要件、名前、住所の3つの情報を抽出し、以下のフォーマットで整理してください:\n\nご要件:[内容を自然な日本語で記述]\n\nお名前:[名前を記述]\n\nご住所:[住所を記述]\n\nなお、情報が不足している場合は「情報なし」と記載してください。\n余計な説明は不要です。上記フォーマットのみを返してください。\n\nテキスト:\n' & $recording %}"
}
]
}
]
}
}
変数recording
を利用する場合、以下のように記述します。&
を挟んで使用します。
"text": "`{% '固定のプロンプト内容' & $recording %}`"
実行すると、タスク結果や状態の出力として、以下のように整形された文章が確認できます。
{
"Body": {
"id": "msg_bdrk_011VHFJaWYZobCUWnFBzi7h2",
"type": "message",
"role": "assistant",
"model": "claude-3-5-sonnet-20240620",
"content": [
{
"type": "text",
"text": "ご要件:加湿器が壊れたので連絡した。15時にまた連絡してほしい。\n\nお名前:シライ ユウジ\n\nご住所:情報なし"
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 211,
"output_tokens": 59
}
},
"ContentType": "application/json"
}
変数
実行結果であるステートの出力のうち、Bedrockで整形された文章(キー名text
)を、次のステートであるSNS Publishでメール通知するために変数として設定します。
{
"Body": {
~中略~
"content": [
{
"type": "text",
"text": "ご要件:加湿器が壊れたので連絡した。15時にまた連絡してほしい。\n\nお名前:シライ ユウジ\n\nご住所:情報なし"
}
],
以下で変数にできます。今回は変数名はbedrock_text
にしています。
{
"bedrock_text": "{% $states.result.Body.content[type=\"text\"].text %}"
}
実行結果を変数にするため、$states.result
を使用します。
JSONataでは、Body.content[type=\"text\"].text
と記述することでキー名text
を指定できます。
Task stateのresults
AWS サービスの連携ステート(Task state)を利用する場合、リクエスト結果を$states.result
として変数にすることはできます。
$states.result
は、API が成功した場合の結果を指します。
ステートの入力を引数や変数として利用する場合は、"{% $states.input.xxx.xxx %}"
と記述します。
また、実行結果であるステートの出力を変数として利用する場合は、"{% $states.result.xxx.xxx %}"
と記述します。
設定
設定は以下の通りです。設定タブの[Bedrockモデルパラメータ]には、引数のBodyの設定値がそのまま表示されています。
SNS Publish
最後に、SNS Publishステートについて解説します。
引数
SNS Publishステートでは、メール本文にPass state(ParseJSON)ステート、Choiceステート、InvokeModelステートで設定した変数を利用します。
SNS Publishを実行するには、引数としてメール本文(Message)とSNSトピックARNが必要です。
メール送信先であるトピックARNには固定値を使用しています。
引数には、以下の変数を使用します。
- Pass state(ParseJSON)ステートで設定した変数
$InitialContactId
:コンタクトID$Time
:問い合わせが開始された日時$CallerPhoneNumber
:発信元電話番号
- Choiceステートで設定した変数
$recording
:コンタクト属性recording
(文字起こし内容)
- InvokeModelステートで設定した変数
$bedrock_text
:recording
(文字起こし内容)をBedrockで整形した文章
メール本文(Message)とSNSトピックARNを以下のように設定しました。
{
"Message": "{% 'お問い合わせ情報\n\n Contact ID: ' & $InitialContactId & '\n\n・日時:' & $Time & '\n\n・電話番号:' & $CallerPhoneNumber & '\n\n・お問い合わせ内容(整形済み文章)' & '\n\n' & $bedrock_text & '\n\n・お問い合わせ内容(未整形文章)' & '\n\n' & $recording %}",
"TopicArn": "arn:aws:sns:ap-northeast-1:xxxxxxxx:cm-hirai"
}
実際に送信されるメールの内容例は以下の通りです。
お問い合わせ情報
Contact ID: 78c0a317-4e6f-40e3-b035-4bb8e879b15f
・日時:2024-11-27T01:02:59.076Z
・電話番号:+81xxxxxxxx
・お問い合わせ内容(整形済み文章)
ご要件:先週水曜日に注文した商品が届かず、確認メールも来ていないため、注文状況を確認したい。
お名前:サトウ タロウ
ご住所:東京都港区西新橋1-1-1 日比谷ポートタワー 16階
・お問い合わせ内容(未整形文章)
東京 都 港 区 西新橋 一 の 一 の 一 に 住ん で いる サトウ タロウ と 申し ます 先日 で も 問い合わせ し た ん です が 返事 が なく て 注文 し た 商品 が まだ 届か ない の で 確認 し たく て 電話 し まし た 注文 番号 は わかり ませ ん 住所 は 先程 言っ た 通り な ん です が マンション 名 を 言い 忘れ まし た 日比谷 ポート タワー に 十 六 回 です 実 は 先週 の 水曜 日 に 注文 し た はず な ん です が 確認 メール も 来 なく て 心配 です 普段 は 二 三 日 で 届く と 聞い て い た の で もし か し たら 注文 が 正しく 完了 し て い ない の か な と 思っ て 商品 は 確か 合計 で 一 万 二 千 八 百 円 分 注文 し た ん です が クレジット カード の 引き落とし も 確認 でき て い ませ ん
設定
設定は以下のようになります。設定の [メッセージ] には、引数の Message の設定値が表示されています。
{% 'お問い合わせ情報
Contact ID: ' & $InitialContactId & '
・日時:' & $Time & '
・電話番号:' & $CallerPhoneNumber & '
・お問い合わせ内容(整形済み文章)' & '
' & $bedrock_text & '
・お問い合わせ内容(未整形文章)' & '
' & $recording %}
ステートマシン実行してみた
KDSからステートマシンがトリガーされると、以下のような内容のメールが通知されました。
今回利用した全体のステートは以下の通りです。
全体のステート(クリックで展開)
{
"Comment": "Voicemail to Email Notifier State Machine with JSONata",
"StartAt": "Base64Decode",
"QueryLanguage": "JSONata",
"States": {
"Base64Decode": {
"Type": "Pass",
"Next": "ParseJSON",
"Assign": {
"decodedData": "{% $base64decode($states.input.data) %}"
}
},
"ParseJSON": {
"Type": "Pass",
"Next": "Choice",
"Assign": {
"data": "{% $parse($decodedData) %}",
"InitialContactId": "{% $parse($decodedData).ContactId %}",
"Time": "{% $parse($decodedData).InitiationTimestamp %}",
"CallerPhoneNumber": "{% $parse($decodedData).SystemEndpoint.Address %}"
}
},
"Choice": {
"Type": "Choice",
"Choices": [
{
"Condition": "{% $data.Attributes.recording != null %}",
"Next": "Bedrock InvokeModel",
"Assign": {
"recording": "{% $data.Attributes.recording %}"
}
}
],
"Default": "Pass"
},
"Bedrock InvokeModel": {
"Type": "Task",
"Resource": "arn:aws:states:::bedrock:invokeModel",
"Arguments": {
"ModelId": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0",
"Body": {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"temperature": 0,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "{% '以下の音声文字起こしテキストから、ご要件、名前、住所の3つの情報を抽出し、以下のフォーマットで整理してください:\n\nご要件:[内容を自然な日本語で記述]\n\nお名前:[名前を記述]\n\nご住所:[住所を記述]\n\nなお、情報が不足している場合は「情報なし」と記載してください。\n余計な説明は不要です。上記フォーマットのみを返してください。\n\nテキスト:\n' & $recording %}"
}
]
}
]
}
},
"Next": "SNS Publish",
"Assign": {
"bedrock_text": "{% $states.result.Body.content[type=\"text\"].text %}"
}
},
"SNS Publish": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Arguments": {
"Message": "{% 'お問い合わせ情報\n\n Contact ID: ' & $InitialContactId & '\n\n・日時:' & $Time & '\n\n・電話番号:' & $CallerPhoneNumber & '\n\n・お問い合わせ内容(整形済み文章)' & '\n\n' & $bedrock_text & '\n\n・お問い合わせ内容(未整形文章)' & '\n\n' & $recording %}",
"TopicArn": "arn:aws:sns:ap-northeast-1:012345678901:cm-hirai"
},
"End": true
},
"Pass": {
"Type": "Pass",
"Comment": "No recording attribute found, ending workflow.",
"End": true
}
}
}
参考